 /*
 * IBlas.cs
 * 
 * This provides our interface to BLAS routines.
 * 
 * Copyright (c) 2005, dnAnalytics. All rights reserved.
 */

namespace dnAnalytics.Nli {
	/// <summary>
	/// An enumeration of the available BLAS providers.
	/// </summary>
	public enum BlasProvider {
		/// <summary>
		/// Provider for AMD's ACML.
		/// </summary>
		Acml,

		/// <summary>
		/// Provider for the ATLAS library.
		/// </summary>
		Atlas,

		/// <summary>
		/// Provider for INTEL's Math Kernel Libary.
		/// </summary>
		Mkl
	}

	/// <summary>
	/// The class provides access to the the various BLAS providers.
	/// </summary>
	public class Blas {
		private Blas() {}

		/// <summary>
		/// The method returns an <see cref="IBlas"/> interface for the requested BLAS provider.
		/// </summary>
		/// <param name="provider">The <see cref="BlasProvider"/> to return.</param>
		/// <returns>An <see cref="IBlas"/> interface for the requested BLAS provider.</returns>
		public static IBlas Provider(BlasProvider provider) {
			switch (provider) {
				case BlasProvider.Acml:
					return Acml.Blas.Instance;
				case BlasProvider.Atlas:
					return AtlasClapack.Blas.Instance;
				case BlasProvider.Mkl:
					return Mkl.Blas.Instance;
				default:
					return null;
			}
		}
	}

	#region BLAS enums

	/// <summary>
	/// The matrix data storage format.
	/// </summary>
	public enum BlasOrderType {
		/// <summary>
		/// The matrix array uses a row-major layout.
		/// </summary>
		Row = 101,

		/// <summary>
		/// The matrix array uses a column-major layout.
		/// </summary>
		Column = 102
	}

	/// <summary>
	/// Matrix transpose type.
	/// </summary>
	public enum BlasTransType {
		/// <summary>
		/// Don't transpose the matrix.
		/// </summary>
		NoTrans = 111,

		/// <summary>
		/// Transpose the matrix.
		/// </summary>
		Trans = 112,

		/// <summary>
		/// Conjugate transpose the matrix. The only refers to complex matrices. Real matrices will just be transposed.
		/// </summary>
		ConjTrans = 113
	}

	/// <summary>
	/// Triangular matrix type.
	/// </summary>
	public enum BlasUpLoType {
		/// <summary>
		/// Data is stored in the upper triangle of the matrix.
		/// </summary>
		Upper = 121,

		/// <summary>
		/// Data is stored in the lower triangle of the matrix.
		/// </summary>
		Lower = 122
	}

	/// <summary>
	/// Specifies whether a matrix is unit triangular.
	/// </summary>
	public enum BlasDiagType {
		/// <summary>
		/// The matrix is not unit triangular.
		/// </summary>
		NonUnit = 131,

		/// <summary>
		/// The matrix is unit triangular.
		/// </summary>
		Unit = 132
	}

	/// <summary>
	/// Matrix side to apply an operation. 
	/// </summary>
	public enum BlasSideType {
		/// <summary>
		/// Left side of the matrix.
		/// </summary>
		Left = 141,

		/// <summary>
		/// Right side of the matrix.
		/// </summary>
		Right = 142
	}

	#endregion BLAS enums	

	/// <summary>
	/// Interface for BLAS routines.
	/// </summary>
	public interface IBlas {
		#region BLAS1 Routines

		/// <summary>
		/// Computes a vector-vector dot product.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		float Sdot(int n, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Computes a vector-vector dot product.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		double Ddot(int n, double[] x, int incX, double[] y, int incY);

		/// <summary>
		/// Computes a vector-vector dot product with extended precision.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		double Dsdot(int n, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Computes a vector-vector dot product with extended precision.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="sb">A scalar to be added to the dot product.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, sb otherwise.</returns>
		float Sdsdot(int n, float sb, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Computes a vector-vector dot product.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		ComplexFloat Cdotu_sub(int n, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY);

		/// <summary>
		/// Computes the dot product of conjugated vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		ComplexFloat Cdotc_sub(int n, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY);

		/// <summary>
		/// Computes a vector-vector dot product.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		ComplexDouble Zdotu_sub(int n, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY);

		/// <summary>
		/// Computes the dot product of conjugated vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <returns>The dot product if <paramref name="n"/> &gt; 0, 0 otherwise.</returns>
		ComplexDouble Zdotc_sub(int n, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY);

		/// <summary>
		/// Computes the Euclidean norm of a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The Euclidean norm.</returns>
		float Snrm2(int n, float[] x, int incX);

		/// <summary>
		/// Calculate the sum of magnitudes of the vector elements.
		/// </summary>
		/// <param name="n">The order of <paramref name="x"/>.</param>
		/// <param name="x">The vector to sum with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The sum of magnitudes of the vector elements</returns>
		float Sasum(int n, float[] x, int incX);

		/// <summary>
		/// Computes the Euclidean norm of a vector.
		/// </summary>
		/// <param name="n">order of the vector.</param>
		/// <param name="x">vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>the Euclidean norm.</returns>
		double Dnrm2(int n, double[] x, int incX);

		/// <summary>
		/// Calculate the sum of magnitudes of the vector elements.
		/// </summary>
		/// <param name="n">The order of <paramref name="x"/>.</param>
		/// <param name="x">The vector to sum with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The sum of magnitudes of the vector elements</returns>
		double Dasum(int n, double[] x, int incX);

		/// <summary>
		/// Computes the Euclidean norm of a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The Euclidean norm.</returns>
		float Scnrm2(int n, ComplexFloat[] x, int incX);

		/// <summary>
		/// Calculate the sum of magnitudes of the vector elements (the magnitude of if the real part plus the magnitude of the imaginary part).
		/// </summary>
		/// <param name="n">The order of <paramref name="x"/>.</param>
		/// <param name="x">The vector to sum with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>sum of magnitudes of the vector elements</returns>
		float Scasum(int n, ComplexFloat[] x, int incX);

		/// <summary>
		/// Computes the Euclidean norm of a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>the Euclidean norm.</returns>
		double Dznrm2(int n, ComplexDouble[] x, int incX);

		/// <summary>
		/// Calculate the sum of magnitudes of the vector elements (the magnitude of if the real part plus the magnitude of the imaginary part).
		/// </summary>
		/// <param name="n">The order of <paramref name="x"/>.</param>
		/// <param name="x">A vector to sum with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>sum of magnitudes of the vector elements</returns>
		double Dzasum(int n, ComplexDouble[] x, int incX);

		/// <summary>
		/// Returns the position of the element with the largest absolute value.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The position of the element with the largest absolute value.</returns>
		int Isamax(int n, float[] x, int incX);

		/// <summary>
		/// Returns the position of the element with the largest absolute value.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The position of the element with the largest absolute value.</returns>
		int Idamax(int n, double[] x, int incX);

		/// <summary>
		/// Returns the position of the element with the largest sum of the absolute value of the real component
		/// the absolute value of the imaginary part.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>The position of the element with the largest sum of the absolute value of the real component
		/// the absolute value of the imaginary part.</returns>
		int Icamax(int n, ComplexFloat[] x, int incX);

		/// <summary>
		/// Returns the position of the element with the largest sum of the absolute value of the real component
		/// the absolute value of the imaginary part.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <returns>the position of the element with the largest sum of the absolute value of the real component
		/// the absolute value of the imaginary part.</returns>
		int Izamax(int n, ComplexDouble[] x, int incX);

		/// <summary>
		/// Swaps the values of one vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Sswap(int n, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Copies the values form vector to another, from x to y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector to copy from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector to copy to with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Scopy(int n, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Performs the operation y = alpha * x + y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to multiply <paramref name="x"/> with.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Saxpy(int n, float alpha, float[] x, int incX, float[] y, int incY);

		/// <summary>
		/// Calculates the values of a Givens rotation.
		/// </summary>
		/// <param name="a">On entry, the <paramref name="x"/> coordinate of a point. On exit, 
		/// it is the r value of a Givens rotation.</param>
		/// <param name="b">On entry, the <paramref name="y"/> coordinate of a point. On exit, 
		/// is is the z value of a Givens rotation.</param>
		/// <param name="c">On exit, it is cosine of the angle of rotation of a Givens rotation.</param>
		/// <param name="s">On exit, it is sine of the angle of rotation of a Givens rotation.</param>
		void Srotg(ref float a, ref float b, out float c, out float s);

		/// <summary>
		/// Swaps the values of one vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dswap(int n, double[] x, int incX, double[] y, int incY);

		/// <summary>
		/// Copies the values form vector to another, from x to y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector to copy from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector to copy to with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dcopy(int n, double[] x, int incX, double[] y, int incY);

		/// <summary>
		/// Performs the operation y = alpha * x + y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to multiply <paramref name="x"/> with.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Daxpy(int n, double alpha, double[] x, int incX, double[] y, int incY);

		/// <summary>
		/// Calculates the values of a Givens rotation.
		/// </summary>
		/// <param name="a">On entry, the <paramref name="x"/> coordinate of a point. On exit, 
		/// it is the r value of a Givens rotation.</param>
		/// <param name="b">On entry, the <paramref name="y"/> coordinate of a point. On exit, 
		/// is is the z value of a Givens rotation.</param>
		/// <param name="c">On exit, it is cosine of the angle of rotation of a Givens rotation.</param>
		/// <param name="s">On exit, it is sine of the angle of rotation of a Givens rotation.</param>
		void Drotg(ref double a, ref double b, out double c, out double s);

		/// <summary>
		/// Swaps the values of one vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Cswap(int n, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY);

		/// <summary>
		/// Copies the values form vector to another, from x to y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector to copy from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector to copy to with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Ccopy(int n, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY);

		/// <summary>
		/// Performs the operation y = alpha * x + y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to multiply <paramref name="x"/> with.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Caxpy(int n, ComplexFloat alpha, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY);

		/// <summary>
		/// Calculates the values of a Givens rotation.
		/// </summary>
		/// <param name="a">On entry, the <paramref name="x"/> coordinate of a point. On exit, 
		/// it is the r value of a Givens rotation.</param>
		/// <param name="b">On entry, the <paramref name="y"/> coordinate of a point. On exit, 
		/// is is the z value of a Givens rotation.</param>
		/// <param name="c">On exit, it is cosine of the angle of rotation of a Givens rotation.</param>
		/// <param name="s">On exit, it is sine of the angle of rotation of a Givens rotation.</param>
		void Crotg(ref ComplexFloat a, ref ComplexFloat b, out ComplexFloat c, out ComplexFloat s);

		/// <summary>
		/// Swaps the values of one vector with another vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zswap(int n, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY);

		/// <summary>
		/// Copies the values form vector to another, from x to y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">A vector to copy from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector to copy to with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zcopy(int n, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY);

		/// <summary>
		/// Performs the operation y = alpha * x + y.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to multiply <paramref name="x"/> with.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zaxpy(int n, ComplexDouble alpha, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY);

		/// <summary>
		/// Calculates the values of a Givens rotation.
		/// </summary>
		/// <param name="a">On entry, the <paramref name="x"/> coordinate of a point. On exit, 
		/// it is the r value of a Givens rotation.</param>
		/// <param name="b">On entry, the <paramref name="y"/> coordinate of a point. On exit, 
		/// is is the z value of a Givens rotation.</param>
		/// <param name="c">On exit, it is cosine of the angle of rotation of a Givens rotation.</param>
		/// <param name="s">On exit, it is sine of the angle of rotation of a Givens rotation.</param>
		void Zrotg(ref ComplexDouble a, ref ComplexDouble b, out ComplexDouble c, out ComplexDouble s);

		/// <summary>
		/// Calculates the values of a modified Givens rotation.
		/// </summary>
		/// <param name="d1">The scale factor for <paramref name="x1"/>.</param>
		/// <param name="d2">The scale factor for <paramref name="y1"/>.</param>
		/// <param name="x1">The first element x(1) of the input vector.</param>
		/// <param name="y1">The second element y(1) of the input vector.</param>
		/// <param name="p">On exit, p has a length of five and contains an array defining 
		/// the type of transform matrix H constructed.</param>
		void Srotmg(ref float d1, ref float d2, ref float x1, float y1, out float[] p);

		/// <summary>
		/// Rotates points on a plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with c*x + s*y.</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="y"/>  are over written with c*x - s*y.</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="c">The cosine of the angle of rotation.</param>
		/// <param name="s">The sine of the angle of rotation.</param>
		void Srot(int n, float[] x, int incX, float[] y, int incY, float c, float s);

		/// <summary>
		/// Rotates points on a modified plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with H[0,0]*x[i] + H[0,1]*y[i].</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with H[1,0]*x[i] + H[1,1]*y[i].</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="p">A vector with a length of five defining the transformation matrix H.</param>
		void Srotm(int n, float[] x, int incX, float[] y, int incY, float[] p);

		/// <summary>
		/// Calculates the values of a modified Givens rotation.
		/// </summary>
		/// <param name="d1">The scale factor for <paramref name="x1"/>.</param>
		/// <param name="d2">The scale factor for <paramref name="y1"/>.</param>
		/// <param name="x1">The first element x(1) of the input vector.</param>
		/// <param name="y1">The second element y(1) of the input vector.</param>
		/// <param name="p">On exit, p has a length of five and contains an array defining 
		/// the type of transform matrix H constructed.</param>
		void Drotmg(ref double d1, ref double d2, ref double x1, double y1, out double[] p);

		/// <summary>
		/// Rotates points on a plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with c*x + s*y.</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="y"/>  are over written with c*x - s*y.</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="c">The cosine of the angle of rotation.</param>
		/// <param name="s">The sine of the angle of rotation.</param>
		void Drot(int n, double[] x, int incX, double[] y, int incY, double c, double s);

		/// <summary>
		/// Rotates points on a modified plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with H[0,0]*x[i] + H[0,1]*y[i].</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with H[1,0]*x[i] + H[1,1]*y[i].</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="p">A vector with a length of five defining the transformation matrix H.</param>
		void Drotm(int n, double[] x, int incX, double[] y, int incY, double[] p);

		/// <summary>
		/// Rotates points on a plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with c*x + s*y.</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="y"/>  are over written with c*x - s*y.</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="c">The cosine of the angle of rotation.</param>
		/// <param name="s">The sine of the angle of rotation.</param>
		void Csrot(int n, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY, float c, float s);

		/// <summary>
		/// Rotates points on a plane.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="x">On entry, a vector containing the <paramref name="x"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).
		/// On exit, the values of <paramref name="x"/>  are over written with c*x + s*y.</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">On entry, a vector containing the <paramref name="y"/> coordinates from with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incY"/>).
		/// On exit, the values of <paramref name="y"/>  are over written with c*x - s*y.</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="c">The cosine of the angle of rotation.</param>
		/// <param name="s">The sine of the angle of rotation.</param>
		void Zdrot(int n, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY, double c, double s);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Sscal(int n, float alpha, float[] x, int incX);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dscal(int n, double alpha, double[] x, int incX);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Cscal(int n, ComplexFloat alpha, ComplexFloat[] x, int incX);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vector.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Zscal(int n, ComplexDouble alpha, ComplexDouble[] x, int incX);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Csscal(int n, float alpha, ComplexFloat[] x, int incX);

		/// <summary>
		/// Scales a vector.
		/// </summary>
		/// <param name="n">The order of the vectors.</param>
		/// <param name="alpha">The scalar to scale <paramref name="x"/> by.</param>
		/// <param name="x">A vector with a length of at least 1+(<paramref name="n"/>-1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Zdscal(int n, double alpha, ComplexDouble[] x, int incX);

		#endregion BLAS1 Routines

		#region BLAS2 Routines

		/// <summary>
		/// Multiplies a matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Sgemv(BlasOrderType order, BlasTransType transA, int m, int n, float alpha, float[] a, int lda, float[] x, int incX, float beta, float[] y, int incY);

		/// <summary>
		/// Multiplies a band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="kl">The number of sub-diagonals of <paramref name="a"/>. <paramref name="kl"/>&gt;=0.</param>
		/// <param name="ku">The number of super-diagonals of <paramref name="a"/>. <paramref name="ku"/>&gt;=0.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least ku+kl+1.</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Sgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, float alpha, float[] a, int lda, float[] x, int incX, float beta, float[] y, int incY);

		/// <summary>
		/// Multiplies a triangular matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Strmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, float[] a, int lda, float[] x, int incX);

		/// <summary>
		/// Multiplies a triangular, band matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Stbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, float[] a, int lda, float[] x, int incX);

		/// <summary>
		/// Multiplies a packed triangular matrix (a) and a vector (x). x =  ap * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix to multiply. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Stpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, float[] ap, float[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Strsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, float[] a, int lda, float[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular, band matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Stbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, float[] a, int lda, float[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (ap) is a packed triangular matrix. Solves for x in, ap * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix containing the equation coefficients. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Stpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, float[] ap, float[] x, int incX);

		/// <summary>
		/// Multiplies a matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dgemv(BlasOrderType order, BlasTransType transA, int m, int n, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY);

		/// <summary>
		/// Multiplies a band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="kl">The number of sub-diagonals of <paramref name="a"/>. <paramref name="kl"/>&gt;=0.</param>
		/// <param name="ku">The number of super-diagonals of <paramref name="a"/>. <paramref name="ku"/>&gt;=0.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least ku+kl+1.</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY);

		/// <summary>
		/// Multiplies a triangular matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtrmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] a, int lda, double[] x, int incX);

		/// <summary>
		/// Multiplies a triangular, band matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, double[] a, int lda, double[] x, int incX);

		/// <summary>
		/// Multiplies a packed triangular matrix (a) and a vector (x). x =  ap * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix to multiply. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] ap, double[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtrsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] a, int lda, double[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular, band matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, double[] a, int lda, double[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (ap) is a packed triangular matrix. Solves for x in, ap * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix containing the equation coefficients. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Dtpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, double[] ap, double[] x, int incX);

		/// <summary>
		/// Multiplies a matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Cgemv(BlasOrderType order, BlasTransType transA, int m, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX, ComplexFloat beta, ComplexFloat[] y, int incY);

		/// <summary>
		/// Multiplies a band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="kl">The number of sub-diagonals of <paramref name="a"/>. <paramref name="kl"/>&gt;=0.</param>
		/// <param name="ku">The number of super-diagonals of <paramref name="a"/>. <paramref name="ku"/>&gt;=0.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least ku+kl+1.</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Cgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX, ComplexFloat beta, ComplexFloat[] y, int incY);

		/// <summary>
		/// Multiplies a triangular matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctrmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX);

		/// <summary>
		/// Multiplies a triangular, band matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX);

		/// <summary>
		/// Multiplies a packed triangular matrix (a) and a vector (x). x =  ap * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix to multiply. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexFloat[] ap, ComplexFloat[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctrsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular, band matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (ap) is a packed triangular matrix. Solves for x in, ap * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix containing the equation coefficients. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ctpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexFloat[] ap, ComplexFloat[] x, int incX);

		/// <summary>
		/// Multiplies a matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zgemv(BlasOrderType order, BlasTransType transA, int m, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX, ComplexDouble beta, ComplexDouble[] y, int incY);

		/// <summary>
		/// Multiplies a band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="kl">The number of sub-diagonals of <paramref name="a"/>. <paramref name="kl"/>&gt;=0.</param>
		/// <param name="ku">The number of super-diagonals of <paramref name="a"/>. <paramref name="ku"/>&gt;=0.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least ku+kl+1.</param>
		/// <param name="x">The vector to multiply with. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). Otherwise, <c>x</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. If <paramref name="transA"/> == <see cref="BlasTransType.NoTrans"/>, then <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incY"/>). Otherwise, <c>y</c> must have a 
		/// length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zgbmv(BlasOrderType order, BlasTransType transA, int m, int n, int kl, int ku, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX, ComplexDouble beta, ComplexDouble[] y, int incY);

		/// <summary>
		/// Multiplies a triangular matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztrmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX);

		/// <summary>
		/// Multiplies a triangular, band matrix (a) and a vector (x). x = a * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztbmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX);

		/// <summary>
		/// Multiplies a packed triangular matrix (a) and a vector (x). x =  ap * x.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix to multiply. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztpmv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexDouble[] ap, ComplexDouble[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztrsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (a) is a triangular, band matrix. Solves for x in, a * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="a"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals or sub-diagonals.</param>
		/// <param name="a">The matrix containing the equation coefficients. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztbsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, int k, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX);

		/// <summary>
		/// Solves a system of linear equations when a matrix (ap) is a packed triangular matrix. Solves for x in, ap * x = b
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/> is an upper or lower
		/// triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="ap"/>.</param>
		/// <param name="diag">The <see cref="BlasDiagType"/> specifying if <paramref name="ap"/> is unit triangular or not.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="ap">The matrix containing the equation coefficients. The length of <paramref name="ap"/> must be at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">On entry, x contains the values of the b vector. On exit, x contains the solution values. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>). </param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		void Ztpsv(BlasOrderType order, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int n, ComplexDouble[] ap, ComplexDouble[] x, int incX);

		/// <summary>
		/// Multiplies a symmetric matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Ssymv(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] a, int lda, float[] x, int incX, float beta, float[] y, int incY);

		/// <summary>
		/// Multiplies a symmetric, band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Ssbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, float alpha, float[] a, int lda, float[] x, int incX, float beta, float[] y, int incY);

		/// <summary>
		/// Multiplies a packed symmetric matrix (ap) and a vector (x) and adds the result to another vector (y). y = alpha * ap * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="ap"/> by.</param>
		/// <param name="ap">The matrix to multiply. <paramref name="ap"/> must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*ap*x. On exit, contains
		/// the result of alpha*ap*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Sspmv(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] ap, float[] x, int incX, float beta, float[] y, int incY);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * y' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Sger(BlasOrderType order, int m, int n, float alpha, float[] x, int incX, float[] y, int incY, float[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a symmetric matrix. a = alpha * x * x' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*x' with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. On exit, 
		/// it contains the result of alpha*x*x'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Ssyr(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] x, int incX, float[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a symmetric, packed matrix. ap = alpha * x * x' + ap.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*x' with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="ap">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. It must
		/// have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. On exit, it contains the result of alpha*x*x'+ap.</param>
		void Sspr(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] x, int incX, float[] ap);

		/// <summary>
		/// Computes the rank-2 update of a symmetric matrix. a = alpha * x * y' + alpha *y * x' + a
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">The matrix to update. On exit, it contains the result of alpha * x * y' + alpha *y * x' + a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Ssyr2(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] x, int incX, float[] y, int incY, float[] a, int lda);

		/// <summary>
		/// Computes the rank-2 update of a symmetric, packed matrix. ap = alpha * x * y' + alpha *y * x' + ap
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="ap">The matrix to update.  It must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.
		/// On exit, it contains the result of alpha * x * y' + alpha *y * x' + ap.</param>
		void Sspr2(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, float[] x, int incX, float[] y, int incY, float[] ap);

		/// <summary>
		/// Multiplies a symmetric matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dsymv(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY);

		/// <summary>
		/// Multiplies a symmetric, band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least k+1.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*a*x. On exit, contains
		/// the result of alpha*a*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dsbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, double alpha, double[] a, int lda, double[] x, int incX, double beta, double[] y, int incY);

		/// <summary>
		/// Multiplies a packed symmetric matrix (ap) and a vector (x) and adds the result to another vector (y). y = alpha * ap * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="ap"/> by.</param>
		/// <param name="ap">The matrix to multiply. <paramref name="ap"/> must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">The vector to multiply with. <c>x</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">On entry, the vector to add to the result of alpha*ap*x. On exit, contains
		/// the result of alpha*ap*x + beta*y. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Dspmv(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] ap, double[] x, int incX, double beta, double[] y, int incY);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * y' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Dger(BlasOrderType order, int m, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a symmetric matrix. a = alpha * x * x' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*x' with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. On exit, 
		/// it contains the result of alpha*x*x'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Dsyr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a symmetric, packed matrix. ap = alpha * x * x' + ap.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*x' with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="ap">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. On exit, 
		/// it contains the result of alpha*x*x'+ap.</param>
		void Dspr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] ap);

		/// <summary>
		/// Computes the rank-2 update of a symmetric matrix. a = alpha * x * y' + alpha *y * x' + a
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">The matrix to update. On exit, it contains the result of alpha * x * y' + alpha *y * x' + a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Dsyr2(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] a, int lda);

		/// <summary>
		/// Computes the rank-2 update of a symmetric, packed matrix. ap = alpha * x * y' + alpha *y * x' + ap
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="ap">The matrix to update. It must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. 
		/// On exit, it contains the result of alpha * x * y' + alpha *y * x' + ap.</param>
		void Dspr2(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, double[] x, int incX, double[] y, int incY, double[] ap);

		/// <summary>
		/// Multiplies a Hermitian matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Chemv(BlasOrderType order, BlasUpLoType uplo, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX, ComplexFloat beta, ComplexFloat[] y, int incY);

		/// <summary>
		/// Multiplies a Hermitian, band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Chbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] x, int incX, ComplexFloat beta, ComplexFloat[] y, int incY);

		/// <summary>
		/// Multiplies a Hermitian, packed matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="ap"/> by.</param>
		/// <param name="ap">The matrix to multiply. <paramref name="ap"/> must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Chpmv(BlasOrderType order, BlasUpLoType uplo, int n, ComplexFloat alpha, ComplexFloat[] ap, ComplexFloat[] x, int incX, ComplexFloat beta, ComplexFloat[] y, int incY);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * y' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Cgeru(BlasOrderType order, int m, int n, ComplexFloat alpha, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY, ComplexFloat[] a, int lda);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * Conjugate(y') + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Cgerc(BlasOrderType order, int m, int n, ComplexFloat alpha, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY, ComplexFloat[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a Hermitian matrix. a = alpha * x * Conjugate(x') + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*Conjugate(x') with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. On exit, 
		/// it contains the result of alpha*x*Conjugate(x')+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Cher(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, ComplexFloat[] x, int incX, ComplexFloat[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a Hermitian, packed matrix. ap = alpha * x * Conjugate(x') + ap.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*Conjugate(x') with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="ap">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. It must
		/// have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. On exit, it contains the result of alpha*x*x'+ap.</param>
		void Chpr(BlasOrderType order, BlasUpLoType uplo, int n, float alpha, ComplexFloat[] x, int incX, ComplexFloat[] ap);

		/// <summary>
		/// Computes the rank-2 update of a Hermitian matrix. a = alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + a,
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">The matrix to update. On exit, it contains the result of alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Cher2(BlasOrderType order, BlasUpLoType uplo, int n, ComplexFloat alpha, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY, ComplexFloat[] a, int lda);

		/// <summary>
		/// Computes the rank-2 update of a Hermitian, packed matrix. ap = alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + ap,
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="ap">The matrix to update. It must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. 
		/// On exit, it contains the result of alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + ap.</param>
		void Chpr2(BlasOrderType order, BlasUpLoType uplo, int n, ComplexFloat alpha, ComplexFloat[] x, int incX, ComplexFloat[] y, int incY, ComplexFloat[] ap);


		/// <summary>
		/// Multiplies a Hermitian matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zhemv(BlasOrderType order, BlasUpLoType uplo, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX, ComplexDouble beta, ComplexDouble[] y, int incY);

		/// <summary>
		/// Multiplies a Hermitian, band matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="k">The number of super-diagonals of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="a"/> by.</param>
		/// <param name="a">The matrix to multiply. <paramref name="a"/> must have the dimensions <paramref name="lda"/> by <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zhbmv(BlasOrderType order, BlasUpLoType uplo, int n, int k, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] x, int incX, ComplexDouble beta, ComplexDouble[] y, int incY);

		/// <summary>
		/// Multiplies a Hermitian, packed matrix (a) and a vector (x) and adds the result to another vector (y). y = alpha * a * x + beta * y.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to scale <paramref name="ap"/> by.</param>
		/// <param name="ap">The matrix to multiply. <paramref name="ap"/> must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="beta">A scalar to scale <paramref name="y"/> by.</param>
		/// <param name="y">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		void Zhpmv(BlasOrderType order, BlasUpLoType uplo, int n, ComplexDouble alpha, ComplexDouble[] ap, ComplexDouble[] x, int incX, ComplexDouble beta, ComplexDouble[] y, int incY);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * y' + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Zgeru(BlasOrderType order, int m, int n, ComplexDouble alpha, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY, ComplexDouble[] a, int lda);

		/// <summary>
		/// A rank-1 update of a general matrix. a = alpha * x * Conjugate(y') + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="n">The number of columns of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">A scalar to multiply the matrix created by <paramref name="x"/> and <paramref name="y"/>' with.</param>
		/// <param name="x">The vector to multiply with the transpose of <paramref name="y"/>. <c>x</c> must have a length of at least 1 + (<paramref name="m"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="y"/>'. On exit, 
		/// it contains the result of alpha*x*y'+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least m.</param>
		void Zgerc(BlasOrderType order, int m, int n, ComplexDouble alpha, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY, ComplexDouble[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a Hermitian matrix. a = alpha * x * Conjugate(x') + a.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*Conjugate(x') with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="a">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. On exit, 
		/// it contains the result of alpha*x*Conjugate(x')+a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Zher(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, ComplexDouble[] x, int incX, ComplexDouble[] a, int lda);

		/// <summary>
		/// Computes the rank-1 update of a Hermitian, packed matrix. a = alpha * x * Conjugate(x') + ap.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to multiply x*Conjugate(x') with.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="ap">On entry, the matrix to add to the product of <paramref name="x"/> and <paramref name="x"/>'. It must
		/// have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. On exit, it contains the result of alpha*x*x'+ap.</param>
		void Zhpr(BlasOrderType order, BlasUpLoType uplo, int n, double alpha, ComplexDouble[] x, int incX, ComplexDouble[] ap);

		/// <summary>
		/// Computes the rank-2 update of a Hermitian matrix. a = alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + a,
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="a"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="a"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="a">The matrix to update. On exit, it contains the result of alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + a.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. <paramref name="lda"/> must be at least n.</param>
		void Zher2(BlasOrderType order, BlasUpLoType uplo, int n, ComplexDouble alpha, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY, ComplexDouble[] a, int lda);

		/// <summary>
		/// Computes the rank-2 update of a Hermitian, packed matrix. ap = alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + ap,
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of <paramref name="ap"/>.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="ap"/>'s data is stored in the upper or lower
		/// triangular part of the matrix.</param>
		/// <param name="n">The order of <paramref name="ap"/>. Must be greater than zero.</param>
		/// <param name="alpha">The scalar to use.</param>
		/// <param name="x">A vector with a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incX"/>).</param>
		/// <param name="incX">The number of elements to increment the index of <paramref name="x"/> by.</param>
		/// <param name="y">The vector to multiply with <paramref name="x"/>. The conjugate of each value is used. <c>y</c> must have a length of at least 1 + (<paramref name="n"/> - 1)*abs(<paramref name="incY"/>).</param>
		/// <param name="incY">The number of elements to increment the index of <paramref name="y"/> by.</param>
		/// <param name="ap">The matrix to update. It must have a length of at least (<paramref name="n"/>*(<paramref name="n"/> + 1))/2. 
		/// On exit, it contains the result of alpha * x * Conjugate(y') + Conjugate(alpha) * y * Conjugate(x') + ap.</param>
		void Zhpr2(BlasOrderType order, BlasUpLoType uplo, int n, ComplexDouble alpha, ComplexDouble[] x, int incX, ComplexDouble[] y, int incY, ComplexDouble[] ap);

		#endregion BLAS2 Routines		

		#region BLAS3 Routines

		/// <summary>
		/// Multiplies two matrices and adds the result to a third matrix. c = alpha * a * b  + beta * c, where a, b, and c are matrices.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="transB">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="b"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/> and <paramref name="c"/>. If <paramref name="a"/> has been
		/// transposed, it is the number rows after the transpose. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/> and <paramref name="c"/>. If <paramref name="b"/> has been
		/// transposed, it is the number columns after the transpose. Must be at least zero.</param>
		/// <param name="k">The number of columns of <paramref name="a"/> and the number of rows of <paramref name="b"/>. 
		/// If <paramref name="a"/> or <paramref name="b"/> have been transposed, it is the number of corresponding rows/columns
		/// after the matrix has been transposed. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">One of the matrices to multiply. If <paramref name="a"/> is transposed, then <paramref name="a"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="m"/>, otherwise <paramref name="lda"/> by <paramref name="k"/>.
		/// </param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="a"/> has been transposed, <paramref name="lda"/> 
		/// &gt;= max(1,<paramref name="k"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="b">One of the matrices to multiply. If <paramref name="b"/> is transposed, then <paramref name="b"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="k"/>, otherwise <paramref name="lda"/> by <paramref name="n"/>.
		/// </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. If <paramref name="b"/> has been transposed, <paramref name="ldb"/> 
		/// &gt;= max(1,<paramref name="n"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.
		/// </param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Sgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, float alpha, float[] a, int lda, float[] b, int ldb, float beta, float[] c, int ldc);

		/// <summary>
		/// Multiplies a symmetric matrix (a) with a matrix (b) and adds the result to a third matrix (c). c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A symmetric matrix. If <paramref name="side"/> == <see cref="BlasSideType.Right"/>, then <paramref name="a"/>
		/// is a <paramref name="n"/> by <paramref name="n"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="n"/>.
		/// If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then <paramref name="a"/>
		/// is a <paramref name="m"/> by <paramref name="m"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="m"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> &gt;= max(1,<paramref name="n"/>) matrix. </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>)., otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Ssymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, float alpha, float[] a, int lda, float[] b, int ldb, float beta, float[] c, int ldc);

		/// <summary>
		/// Perform an rank-n update on a symmetric matrix (c).  c = alpha * a * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * a' + beta * c. Otherwise  c = alpha * a' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * a'  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Ssyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, float alpha, float[] a, int lda, float beta, float[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a symmetric matrix (c).  c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// Otherwise c = alpha * a' * b + alpha * b' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b' + alpha * b * a' + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Ssyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, float alpha, float[] a, int lda, float[] b, int ldb, float beta, float[] c, int ldc);

		/// <summary>
		/// Multiplies two matrices where one matrix (a) is a triangular matrix. b = alpha * a * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Strmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, float alpha, float[] a, int lda, float[] b, int ldb);

		/// <summary>
		/// Solve a matrix equation where one matrix (a) is a triangular matrix. a * x = alpha * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*x or x*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the solution matrix x.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Strsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, float alpha, float[] a, int lda, float[] b, int ldb);

		/// <summary>
		/// Multiplies two matrices and adds the result to a third matrix. c = alpha * a * b  + beta * c, where a, b, and c are matrices.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="transB">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="b"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/> and <paramref name="c"/>. If <paramref name="a"/> has been
		/// transposed, it is the number rows after the transpose. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/> and <paramref name="c"/>. If <paramref name="b"/> has been
		/// transposed, it is the number columns after the transpose. Must be at least zero.</param>
		/// <param name="k">The number of columns of <paramref name="a"/> and the number of rows of <paramref name="b"/>. 
		/// If <paramref name="a"/> or <paramref name="b"/> have been transposed, it is the number of corresponding rows/columns
		/// after the matrix has been transposed. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">One of the matrices to multiply. If <paramref name="a"/> is transposed, then <paramref name="a"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="m"/>, otherwise <paramref name="lda"/> by <paramref name="k"/>.
		/// </param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="a"/> has been transposed, <paramref name="lda"/> 
		/// &gt;= max(1,<paramref name="k"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="b">One of the matrices to multiply. If <paramref name="b"/> is transposed, then <paramref name="b"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="k"/>, otherwise <paramref name="lda"/> by <paramref name="n"/>.
		/// </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. If <paramref name="b"/> has been transposed, <paramref name="ldb"/> 
		/// &gt;= max(1,<paramref name="n"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.
		/// </param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Dgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc);

		/// <summary>
		/// Multiplies a symmetric matrix (a) with a matrix (b) and adds the result to a third matrix (c). c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A symmetric matrix. If <paramref name="side"/> == <see cref="BlasSideType.Right"/>, then <paramref name="a"/>
		/// is a <paramref name="n"/> by <paramref name="n"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="n"/>.
		/// If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then <paramref name="a"/>
		/// is a <paramref name="m"/> by <paramref name="m"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="m"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> &gt;= max(1,<paramref name="n"/>) matrix. </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>)., otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Dsymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc);

		/// <summary>
		/// Perform an rank-n update on a symmetric matrix (c).  c = alpha * a * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * a' + beta * c. Otherwise  c = alpha * a' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * a'  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Dsyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, double[] a, int lda, double beta, double[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a symmetric matrix (c).  c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// Otherwise c = alpha * a' * b + alpha * b' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b' + alpha * b * a' + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Dsyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, double[] a, int lda, double[] b, int ldb, double beta, double[] c, int ldc);

		/// <summary>
		/// Multiplies two matrices where one matrix (a) is a triangular matrix. b = alpha * a * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Dtrmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb);

		/// <summary>
		/// Solve a matrix equation where one matrix (a) is a triangular matrix. a * x = alpha * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*x or x*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the solution matrix x.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Dtrsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb);

		/// <summary>
		/// Multiplies two matrices and adds the result to a third matrix. c = alpha * a * b  + beta * c, where a, b, and c are matrices.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="transB">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="b"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/> and <paramref name="c"/>. If <paramref name="a"/> has been
		/// transposed, it is the number rows after the transpose. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/> and <paramref name="c"/>. If <paramref name="b"/> has been
		/// transposed, it is the number columns after the transpose. Must be at least zero.</param>
		/// <param name="k">The number of columns of <paramref name="a"/> and the number of rows of <paramref name="b"/>. 
		/// If <paramref name="a"/> or <paramref name="b"/> have been transposed, it is the number of corresponding rows/columns
		/// after the matrix has been transposed. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">One of the matrices to multiply. If <paramref name="a"/> is transposed, then <paramref name="a"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="m"/>, otherwise <paramref name="lda"/> by <paramref name="k"/>.
		/// </param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="a"/> has been transposed, <paramref name="lda"/> 
		/// &gt;= max(1,<paramref name="k"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="b">One of the matrices to multiply. If <paramref name="b"/> is transposed, then <paramref name="b"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="k"/>, otherwise <paramref name="lda"/> by <paramref name="n"/>.
		/// </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. If <paramref name="b"/> has been transposed, <paramref name="ldb"/> 
		/// &gt;= max(1,<paramref name="n"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.
		/// </param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Cgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb, ComplexFloat beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Multiplies a symmetric matrix (a) with a matrix (b) and adds the result to a third matrix (c). c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A symmetric matrix. If <paramref name="side"/> == <see cref="BlasSideType.Right"/>, then <paramref name="a"/>
		/// is a <paramref name="n"/> by <paramref name="n"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="n"/>.
		/// If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then <paramref name="a"/>
		/// is a <paramref name="m"/> by <paramref name="m"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="m"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> &gt;= max(1,<paramref name="n"/>) matrix. </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>)., otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Csymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb, ComplexFloat beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Perform an rank-n update on a symmetric matrix (c).  c = alpha * a * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * a' + beta * c. Otherwise  c = alpha * a' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * a'  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Csyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a symmetric matrix (c).  c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// Otherwise c = alpha * a' * b + alpha * b' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b' + alpha * b * a' + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Csyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb, ComplexFloat beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Multiplies two matrices where one matrix (a) is a triangular matrix. b = alpha * a * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Ctrmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb);

		/// <summary>
		/// Solve a matrix equation where one matrix (a) is a triangular matrix. a * x = alpha * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*x or x*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the solution matrix x.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Ctrsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb);

		/// <summary>
		/// Multiplies two matrices and adds the result to a third matrix. c = alpha * a * b  + beta * c, where a, b, and c are matrices.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="transB">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="b"/>.</param>
		/// <param name="m">The number of rows of <paramref name="a"/> and <paramref name="c"/>. If <paramref name="a"/> has been
		/// transposed, it is the number rows after the transpose. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/> and <paramref name="c"/>. If <paramref name="b"/> has been
		/// transposed, it is the number columns after the transpose. Must be at least zero.</param>
		/// <param name="k">The number of columns of <paramref name="a"/> and the number of rows of <paramref name="b"/>. 
		/// If <paramref name="a"/> or <paramref name="b"/> have been transposed, it is the number of corresponding rows/columns
		/// after the matrix has been transposed. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">One of the matrices to multiply. If <paramref name="a"/> is transposed, then <paramref name="a"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="m"/>, otherwise <paramref name="lda"/> by <paramref name="k"/>.
		/// </param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="a"/> has been transposed, <paramref name="lda"/> 
		/// &gt;= max(1,<paramref name="k"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="b">One of the matrices to multiply. If <paramref name="b"/> is transposed, then <paramref name="b"/> must have the 
		/// dimensions <paramref name="lda"/> by <paramref name="k"/>, otherwise <paramref name="lda"/> by <paramref name="n"/>.
		/// </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. If <paramref name="b"/> has been transposed, <paramref name="ldb"/> 
		/// &gt;= max(1,<paramref name="n"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.
		/// </param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Zgemm(BlasOrderType order, BlasTransType transA, BlasTransType transB, int m, int n, int k, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb, ComplexDouble beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Multiplies a symmetric matrix (a) with a matrix (b) and adds the result to a third matrix (c). c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A symmetric matrix. If <paramref name="side"/> == <see cref="BlasSideType.Right"/>, then <paramref name="a"/>
		/// is a <paramref name="n"/> by <paramref name="n"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="n"/>.
		/// If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then <paramref name="a"/>
		/// is a <paramref name="m"/> by <paramref name="m"/> matrix with dimensions of <paramref name="lda"/> by <paramref name="m"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> &gt;= max(1,<paramref name="n"/>) matrix. </param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>)., otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Zsymm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb, ComplexDouble beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Perform an rank-n update on a symmetric matrix (c).  c = alpha * a * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * a' + beta * c. Otherwise  c = alpha * a' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * a'  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Zsyrk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a symmetric matrix (c).  c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * b' + alpha * b * a' + beta * c. 
		/// Otherwise c = alpha * a' * b + alpha * b' * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b' + alpha * b * a' + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Zsyr2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb, ComplexDouble beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Multiplies two matrices where one matrix (a) is a triangular matrix. b = alpha * a * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Ztrmm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb);

		/// <summary>
		/// Solve a matrix equation where one matrix (a) is a triangular matrix. a * x = alpha * b.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*x or x*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/> is an upper or lower triangular matrix.</param>
		/// <param name="transA">The <see cref="BlasTransType"/> specifying whether and how to transpose <paramref name="a"/>.</param>
		/// <param name="diag">Specifies whether <paramref name="a"/> is unit triangular.</param>
		/// <param name="m">The number of rows of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="b"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A triangular matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the solution matrix x.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Ztrsm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, BlasTransType transA, BlasDiagType diag, int m, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb);


		/// <summary>
        /// Multiplies two matrices, where one of the matrices (a) is a Hermitian matrix, and adds the result to a third matrix. c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A Hermitian matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Chemm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb, ComplexFloat beta, ComplexFloat[] c, int ldc);

	
		/// <summary>
		/// Perform an rank-n update on a Hermitian matrix (c).  c = alpha * a * Conjugate(a') + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * Conjugate(a') + beta * c. Otherwise  c = alpha * Conjugate(a') * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A Hermitian matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * Conjugate(a')  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Cherk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, float alpha, ComplexFloat[] a, int lda, float beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a Hermitian matrix (c).  c = alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c. 
		/// Otherwise c = alpha * Conjugate(b') * a + Conjugate(alpha) * Conjugate(a') * b + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Cher2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexFloat alpha, ComplexFloat[] a, int lda, ComplexFloat[] b, int ldb, float beta, ComplexFloat[] c, int ldc);

		/// <summary>
		/// Multiplies two matrices, where one of the matrices (a) is a Hermitian matrix, and adds the result to a third matrix. c = alpha * a * b  + beta * c.
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="side">The <see cref="BlasSideType"/> specifying if the multiplication should be a*b or b*a.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="a"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="m">The number of rows of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="n">The number of columns of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A Hermitian matrix with dimensions <paramref name="lda"/> by k matrix, where k == <paramref name="m"/> if <paramref name="side"/> == <see cref="BlasSideType.Left"/>, otherwise
		/// k = <paramref name="n"/>.</param>
		/// <param name="lda">The first dimension of <paramref name="a"/>. If <paramref name="side"/> == <see cref="BlasSideType.Left"/>, then
		/// <paramref name="lda"/> &gt;= max(1,<paramref name="m"/>), otherwise <paramref name="lda"/> &gt;= max(1,<paramref name="n"/>).</param>
		/// <param name="b">b must have the dimensions <paramref name="ldb"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b.</param>
		/// <param name="ldb">The first dimension of <paramref name="b"/>. <paramref name="ldb"/> &gt;= max(1,<paramref name="m"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">The matrix to add to product of <paramref name="a"/> and <paramref name="b"/>. <paramref name="c"/> must have the
		/// dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * b  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="m"/>).</param>
		void Zhemm(BlasOrderType order, BlasSideType side, BlasUpLoType uplo, int m, int n, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb, ComplexDouble beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Perform an rank-n update on a Hermitian matrix (c).  c = alpha * a * Conjugate(a') + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * Conjugate(a') + beta * c. Otherwise  c = alpha * Conjugate(a') * a + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k is the number of columns of <paramref name="a"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A Hermitian matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * Conjugate(a')  + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Zherk(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, double alpha, ComplexDouble[] a, int lda, double beta, ComplexDouble[] c, int ldc);

		/// <summary>
		/// Perform an rank-2k update on a Hermitian matrix (c).  c = alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c. 
		/// </summary>
		/// <param name="order">The <see cref="BlasOrderType"/> specifying the column order of the matrices.</param>
		/// <param name="uplo">The <see cref="BlasUpLoType"/> specifying if <paramref name="c"/>'s data is stored in the upper or lower
		/// part of the matrix.</param>
		/// <param name="trans">If trans == <see cref="BlasTransType.NoTrans"/>, then c = alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c. 
		/// Otherwise c = alpha * Conjugate(b') * a + Conjugate(alpha) * Conjugate(a') * b + beta * c.</param>
		/// <param name="n">The order of <paramref name="c"/>. Must be at least zero.</param>
		/// <param name="k">If trans == <see cref="BlasTransType.NoTrans"/>, then k  is the number of columns of <paramref name="a"/> and <paramref name="b"/>. Otherwise, k is
		/// the number of rows of <paramref name="a"/> and <paramref name="b"/>.</param>
		/// <param name="alpha">A scalar to use.</param>
		/// <param name="a">A <paramref name="lda"/> by ka matrix, where ka == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// ka = <paramref name="n"/>.</param>
		/// <param name="lda">If <paramref name="trans"/> == BlasTransType.NoTrans, then lda must be at least max(1,<paramref name="n"/>). Otherwise lda must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="b">A <paramref name="ldb"/> by kb matrix, where kb == <paramref name="k"/> if <paramref name="trans"/> == <see cref="BlasTransType.NoTrans"/>, otherwise
		/// kb = <paramref name="n"/>.</param>
		/// <param name="ldb">If <paramref name="trans"/> == BlasTransType.NoTrans, then ldb must be at least max(1,<paramref name="n"/>). Otherwise ldb must be at least max(1, <paramref name="k"/>).</param>
		/// <param name="beta">A scalar to use.</param>
		/// <param name="c">A symmetric matrix. c must have the dimensions <paramref name="ldc"/> by <paramref name="n"/>. On exit, it contains the result of alpha * a * Conjugate(b') + Conjugate(alpha) * b * Conjugate(a') + beta * c.</param>
		/// <param name="ldc">The first dimension of <paramref name="c"/>. <paramref name="ldc"/> &gt;= max(1,<paramref name="n"/>).</param>
		void Zher2k(BlasOrderType order, BlasUpLoType uplo, BlasTransType trans, int n, int k, ComplexDouble alpha, ComplexDouble[] a, int lda, ComplexDouble[] b, int ldb, double beta, ComplexDouble[] c, int ldc);

		#endregion BLAS3 Routines
	}
}